package com.dingwen.treasure.kettle.utils;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.dingwen.treasure.kettle.base.enums.BaseEnum;
import com.dingwen.treasure.kettle.exception.EnumMappingException;
import lombok.experimental.UtilityClass;
import org.springframework.http.HttpStatus;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 　EnumUtil 枚举工具类
 * 　@author dingwen
 * 　@date 2022/6/17
 */
@UtilityClass
public class EnumUtil {


    /**
     * 获取枚举列表 </br>
     * <p>Enum --> List<Map<String,Object>>  </p>
     *
     * @param clazz 字节码
     * @return {@link List}<{@link Map}<{@link String}, {@link Object}>>
     */
    public  <T extends Enum<T>> List<Map<String, Object>> getList(Class<Object> clazz) {
        List<T> enums = new ArrayList(Arrays.asList(clazz.getEnumConstants()));
        return enums.stream()
                .map(en -> {
                    try {
                        // 获取方法
                        Method method = clazz.getMethod(BaseEnum.TO_MAP_METHOD_NAME);
                        // 执行方法调用
                        return (Map<String, Object>) method.invoke(en);
                    } catch (Exception e) {
                        return null;
                    }
                })
                .collect(Collectors.toList());
    }

    /**
     * 枚举转换
     *
     */
    public  <E extends BaseEnum> E getEnumByCode(Class<E> eClass, Object code) {
        for (E e : eClass.getEnumConstants()) {
            if (Convert.toStr(e.getCode()).equals(Convert.toStr(code))) {
                return e;
            }
        }
        String message = StrUtil.format("枚举类：{},不存在 code: {}", eClass.getSimpleName(), code);
        throw new EnumMappingException(HttpStatus.BAD_REQUEST.value(), message);
    }

    /**
     * 得到enum信息
     *
     * @param enumClassName 枚举类名字
     * @return {@link List}<{@link Object}>
     */
    public  List<Object> getEnumMap(String enumClassName) {
        // 获取实现类
        Set<Class<Object>> classes = ReflectUtil.getSubclassesBySubClass(BaseEnum.class, BaseEnum.SCAN_PACKAGE);

        // 返回结果
        List<Object> result = new ArrayList<>(classes.size());

        classes.parallelStream()
                // 条件过滤
                .filter(e -> ObjectUtils.nullSafeEquals(BaseEnum.ALL, enumClassName) || e.getSimpleName().equals(enumClassName))
                .forEach(aClass -> {
                    try {
                        // 获取枚举类型名称
                        Map<String, Object> enumInfo = new HashMap<>(classes.size() << 2);
                        BaseEnum[] enumConstants = (BaseEnum[]) aClass.getEnumConstants();
                        Method method = aClass.getMethod(BaseEnum.GET_ENUM_DESCRIPTION_METHOD);
                        String name = String.valueOf(method.invoke(enumConstants[0]));
                        List<Map<String, Object>> maps = EnumUtil.getList(aClass);
                        enumInfo.put(BaseEnum.ENUM_NAME, name);
                        enumInfo.put(BaseEnum.ENUM_TYPE, aClass.getSimpleName());
                        enumInfo.put(BaseEnum.ENUM_VALUE, maps);
                        result.add(enumInfo);
                    } catch (Exception e) {
                        throw new RuntimeException("枚举信息转换异常");
                    }
                });
        return result;
    }
}
